import { ComponentType } from "./ECS";
import { EntityID } from "./Entity";

/**
 * 组件接口
 */
export interface IComponent {
    // create<T extends IComponent>():T;
    // meta(...data:any[]):ComponentMate;
    /**
     * 组件名称,在onCreate中传入设置,无需手动设置
     */
    readonly name:string;
    /**
     * 组件ID
     */
    readonly id:number;
    /**
     * 组件类型,在onCreate中传入设置,无需手动设置
     */
    readonly type:number;
    /**
     * 拥有该组件的实体
     */
    readonly entity:EntityID;
    /**
     * 释放组件,并存放到缓存中.组件未从entity移除时,什么都不会发生.
     */
    release(): void;

    /**
     * 组件被创建时
     * @param type 
     * @param name 
     * @param datas 其他数据
     */
    onCreate(type: number, name: string, ...datas:any[]):void;

    /**
     * 组件被添加到实体上时调用
     * @param entity 
     */
    onAdd(entity: EntityID): void;

    /**
     * 组件被移除时调用
     */
    onRemove(): void;

    /**
     * 组件被释放时调用
     */
    onRelease(): void;
}

export type ComponentClass = {create<T extends Component>():T};
/**
 * 携带了数据的组件创建类型
 */
export type ComponentMate = {clazz:ComponentClass, data?:any[]}|ComponentClass;
/**
 * 基础组件
 */
export class Component implements IComponent {
    private static _componentPool:Component[] = [];

    /**
     * 创建该组件
     * @returns 
     */
    public static create<T extends Component>():T{
        return <T>this._componentPool.pop() || <T>new this();
    }
    /**
     * 释放组件
     * @param component 
     */
    protected static release(component:Component):void {
        component.onRelease();
        this._componentPool.push(component);
    }

    private static nextId: number = 0;
    /**
     * 指定创建组件时携带的数据
     * @param data 数据
     * @returns 
     */
    public static meta(...data:any[]):ComponentMate {
        return {clazz:this, data:data};
    }
    private _id: number = -1;
    /**
     * 组件ID
     */
    public get id(): number {
        return this._id;
    }
    private _type: ComponentType;
    /**
     * 组件类型
     */
    public get type(): ComponentType {
        return this._type;
    }

    private _name: string;
    /**
     * 组件名称
     */
    public get name(): string {
        return this._name;
    }
    protected _entity: EntityID = -1;
    /**
     * 拥有该组件的实体
     */
    public get entity(): EntityID {
        return this._entity;
    }

    constructor() {
        this._id = Component.nextId++;
    }

    /**
     * 组件被创建时
     * @param type 
     * @param name 
     * @param datas 其他数据
     */
    onCreate(type: number, name: string, ...datas:any[]) {
        this._type = type;
        this._name = name;
    }

    /**
     * 组件被添加到实体上时调用
     * @param entity 
     */
    onAdd(entity: EntityID): void {
        this._entity = entity;
    }

    /**
     * 组件被移除时调用
     */
    onRemove(): void {
        this._entity = -1;
        this._id = -1;
    }

    /**
     * 释放组件,并存放到缓存中.组件未从entity移除时,什么都不会发生.
     */
    release(): void {
        if(this.entity != -1){
            return;
        }
        (this.constructor as typeof Component).release(this);
    }

    /**
     * 组件被释放时调用
     */
    onRelease(): void {

    }
}
